#include "Layer.hpp"

namespace maploader
{
	std::string Layer::myEncodingFormat[Layer::Encoding::ECount] = { "base64", "csv", "" };
	std::string Layer::myCompressionFormat[Layer::Compression::CCount] = { "gzip", "zlib", "" };

	Layer::Layer() : myName(""), myOpacity(1), myVisible(true), myEncoding(Layer::Encoding::ECount), myCompression(Layer::Compression::CCount) {}

	Layer Layer::Load(const pugi::xml_node& node, unsigned int width, unsigned int height)
	{
		Layer layer;
		layer.myName = std::string(node.attribute("name").value());
		std::string layerenc = std::string(node.child("data").attribute("encoding").value());
		for (unsigned int i = 0; i < Layer::Encoding::ECount; i++)
			if (Layer::myEncodingFormat[i] == layerenc)
				layer.myEncoding = i;
		if (layer.myEncoding == Layer::Encoding::ECount)
			layer.myEncoding = 0;

		std::string layercomp = std::string(node.child("data").attribute("compression").value());
		for (unsigned int i = 0; i < Layer::Compression::CCount; i++)
			if (Layer::myCompressionFormat[i] == layercomp)
				layer.myCompression = i;
		if (layer.myCompression == Layer::Compression::CCount)
			layer.myCompression = 0;

		layer.myOpacity = node.attribute("opacity").as_float();
		layer.myVisible = node.attribute("visible").as_bool();

		if (layer.myEncoding == Layer::XML)
		{
			layer.myData.resize(height);
			for (unsigned int j = 0; j < height; j++)
				layer.myData[j].resize(width);

			pugi::xml_node tile = node.child("data").child("tile");
			for (unsigned int j = 0; j < height; j++)
				for (unsigned int i = 0; i < width; i++)
				{
					layer.myData[j][i] = tile.attribute("gid").as_uint();
					tile = tile.next_sibling("tile");
				}
		}
		else if (layer.myEncoding == Layer::CSV || layer.myEncoding == Layer::Base64)
		{
			layer.myData.resize(height);
			for (unsigned int j = 0; j < height; j++)
				layer.myData[j].resize(width);

			std::string data;

			if (layer.myEncoding == Layer::CSV)
				data = std::string(node.child("data").child_value());
			else
				data = sl::Encode<64>(std::string(node.child("data").child_value()));

			std::stringstream ss;
			unsigned int uint;

			for (unsigned int j = 0; j < height; j++)
				for (unsigned int i = 0; i < width; i++)
				{
					ss << data.substr(0, data.find(","));
					ss >> uint;
					ss.str("");

					layer.myData[j][i] = uint;
					data = data.substr(data.find(",") + 1);
				}
		}

		return layer;
	}

	std::vector<std::vector<unsigned int> > Layer::GetData()
	{
		return myData;
	}

	std::string Layer::GetName()
	{
		return myName;
	}
}